package com.seadragon.app.ksr.controller;

import static com.seadragon.app.ksr.model.KsrConstants.ENTITY_TYPE_BUSINESS;
import static com.seadragon.app.ksr.model.KsrConstants.ENTITY_TYPE_CUSTOMER;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.SessionStatus;

import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.GsonBuilder;
import com.seadragon.app.ksr.model.Customer;
import com.seadragon.app.ksr.model.KsrConstants;
import com.seadragon.app.ksr.model.Office;
import com.seadragon.app.ksr.model.Review;
import com.seadragon.app.ksr.service.CustomerService;
import com.seadragon.app.ksr.service.OfficeService;
import com.seadragon.app.ksr.service.ReviewService;
import com.seadragon.app.ksr.util.CookieUtil;
import com.seadragon.app.ksr.util.GsonUtils;

@Controller
public class EntityController {

	@Autowired
	private CustomerService customerService;

	@Autowired
	private OfficeService officeService;

	@Autowired
	private ReviewService reviewService;
	
   @RequestMapping("/business.html")
	public String showBusiness(Model model,@RequestParam(value = "id", required = true) String id){
	   model.addAttribute("business", DummyData.getDummyBusiness());
		return "business";
	}
   
   @RequestMapping("/customer/office.html")
   public String showOffice(HttpServletRequest request, HttpServletResponse response,Model model,@RequestParam(value = "id", required = true) String id){
	   if (StringUtils.isNotEmpty(id)){
		   Office office =officeService.findById(new Long(id));
		   if (office!=null){
			   model.addAttribute("office", office);
			   model.addAttribute("reviewsFor5str", reviewService.findByOfficeAndReviewRating(office, 100));
			   model.addAttribute("reviewsFor4str", reviewService.findByOfficeAndReviewRating(office, 80));
			   model.addAttribute("reviewsFor3str", reviewService.findByOfficeAndReviewRating(office, 60));
			   model.addAttribute("reviewsFor2str", reviewService.findByOfficeAndReviewRating(office, 40));
			   model.addAttribute("reviewsFor1str", reviewService.findByOfficeAndReviewRating(office, 20));
			   model.addAttribute("reviewList", reviewService.findByOffice(office));
			   //save cookie
			   try {
					CookieUtil.saveCookie(Long.toString(office.getId()), "office", response, request.getCookies(), request.getContextPath());
				} catch (UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		   }
	   }
//	   model.addAttribute("office", DummyData.getDummyOffice());
//	   model.addAttribute("centerLocation", DummyData.getDummyOffice().getAddress());
//	   model.addAttribute("reviewList", DummyData.getReviewList());
	   return "customer.office";
   }
   
   @RequestMapping(value={"/{pageType}/reviewer.html","/{pageType}/customer.html"})
   public String showReviewer(@PathVariable String pageType, HttpServletRequest request, HttpServletResponse response,Model model,@RequestParam(value = "id", required = true) String id){
	   if (StringUtils.isNotEmpty(id)){
		   Customer reviewer =customerService.findById(new Integer(id));
		   if (reviewer!=null){
			   model.addAttribute("reviewer", reviewer);
			   model.addAttribute("reviewsFor5str", reviewService.findByCustomerAndReviewRating(reviewer, 100));
			   model.addAttribute("reviewsFor4str", reviewService.findByCustomerAndReviewRating(reviewer, 80));
			   model.addAttribute("reviewsFor3str", reviewService.findByCustomerAndReviewRating(reviewer, 60));
			   model.addAttribute("reviewsFor2str", reviewService.findByCustomerAndReviewRating(reviewer, 40));
			   model.addAttribute("reviewsFor1str", reviewService.findByCustomerAndReviewRating(reviewer, 20));
			   model.addAttribute("reviewList", reviewService.findByCustomer(reviewer));
			   //save cookie
			   try {
					CookieUtil.saveCookie(Long.toString(reviewer.getId()), "reviewer", response, request.getCookies(), request.getContextPath());
				} catch (UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}			   
		   }
	   }
	   if ("business".equals(pageType)){
		   return "business.customer";
	   } else {
		   return "customer.reviewer";
	   }
   }
   @RequestMapping(value="/{pageType}/customer-review.html", method = RequestMethod.POST)
   public String saveCustomerReview(@PathVariable String pageType, @ModelAttribute("review") @Valid Review review, BindingResult result, 
		   @RequestParam(value = "office_id", required = true) String officeId,
		   @RequestParam(value = "redirect", required = false) String redirect,
		    SessionStatus status,
			HttpServletRequest request, Model model) {
	   Customer customer = (Customer)request.getSession().getAttribute(KsrConstants.SESSION_SCOPED_CUSTOMER);
	   if (review.getId()>0){ //update review
		   reviewService.update(review);
	   } else { //create a new review
		   Office office = officeService.findById(new Long(officeId));
		   if (review!=null&&office!=null&&customer!=null){
			   review.setCustomer(customer);
			   review.setDateUpdated(new Date());
			   review.setDateCreated(new Date());
			   review.setOffice(office);
			   reviewService.save(review);
		   }
	   }
	   if ("reviewer".equals(redirect)){
		   if ("business".equals(pageType)){
			   return "redirect:/business/customer.html?id="+customer.getId();
		   } else {
			   return "redirect:/customer/reviewer.html?id="+customer.getId();
		   }
	   } else {
		   return "redirect:/customer/office.html?id="+review.getOffice().getId();
	   }
   }
   
   @RequestMapping(value = "/{entityType}/{entityId}/reviewList.json", method = RequestMethod.GET)
	public @ResponseBody
	String showCustomerProfileJson(HttpServletRequest request, HttpSession session,
			@PathVariable String entityType,
			@PathVariable long entityId,
			@RequestParam(value = "rating", required = false,defaultValue="-1") int rating,
			@RequestParam(value = "pageSize", required = false,defaultValue="-1") int pageSize,
			@RequestParam(value = "pageOffset", required = false,defaultValue="-1") int pageOffset) {
		String reviewStringJson = null;
		List<Review> reviewList = null;
		Map<String,List<Review>> reviewListByRatings = null;
		if (ENTITY_TYPE_BUSINESS.equals(entityType)){
			Office office =officeService.findById(new Long(entityId));
			   if (office!=null){
				 if (rating==100||rating==80||rating==60||rating==40||rating==20){
					 reviewList =reviewService.findByOfficeAndReviewRating(office, rating);
				 } else if (rating == 0){ //all ratings with each in a list
					 reviewListByRatings = new HashMap<>();
					 reviewListByRatings.put("rating100", reviewService.findByOfficeAndReviewRating(office, 100));
					 reviewListByRatings.put("rating80", reviewService.findByOfficeAndReviewRating(office, 80));
					 reviewListByRatings.put("rating60", reviewService.findByOfficeAndReviewRating(office, 60));
					 reviewListByRatings.put("rating40", reviewService.findByOfficeAndReviewRating(office, 40));
					 reviewListByRatings.put("rating20", reviewService.findByOfficeAndReviewRating(office, 20));
				 } else
				   reviewList =reviewService.findByOffice(office);
			   }
		} else if (ENTITY_TYPE_CUSTOMER.equals(entityType)){
			Customer customer =customerService.findById(new Long(entityId));
			   if (customer!=null){
				 if (rating==100||rating==80||rating==60||rating==40||rating==20)
				   reviewList =reviewService.findByCustomerAndReviewRating(customer, rating);
				 else if (rating == 0){ //all ratings with each in a list
					 reviewListByRatings = new HashMap<>();
					 reviewListByRatings.put("rating100", reviewService.findByCustomerAndReviewRating(customer, 100));
					 reviewListByRatings.put("rating80", reviewService.findByCustomerAndReviewRating(customer, 80));
					 reviewListByRatings.put("rating60", reviewService.findByCustomerAndReviewRating(customer, 60));
					 reviewListByRatings.put("rating40", reviewService.findByCustomerAndReviewRating(customer, 40));
					 reviewListByRatings.put("rating20", reviewService.findByCustomerAndReviewRating(customer, 20));
				 } else {
					 reviewList =reviewService.findByCustomer(customer);
				 }
			   }
		}
		if (reviewListByRatings!=null||reviewList!=null){
			reviewStringJson = GsonUtils.ObjectToGson((reviewListByRatings!=null)?reviewListByRatings:reviewList);
		} else {
			reviewStringJson = "";
		}
		
		return reviewStringJson;
	}
   
	@RequestMapping(value = {"/event.html","/customer/event.html"}, method = RequestMethod.GET)
	public String showEventForCustomer(HttpServletRequest request, HttpSession session, Model model) {
		return "customer.event";
	}
}

